var app = angular.module('app', ['ngMessages']);


app.controller('Ctrl', ['$scope','$http', function ($scope,$http) {

	$('.target.popup').popup({
		on: 'click',
		title: 'Popup Title',
		content : 'Hello I am a popup',
		color: '#f00'
	})
	;


	$('.ui.radio.checkbox').checkbox();

	$scope.choose = function(s){
		$scope.radio = s;
	};

	$scope.toolBar = [
	{
		text:'确定',
		type:'button',
		class:'mini primary',
		handel:function(){
			// console.log(this);
			console.log($scope.toolBar);
			alert(1);
		},
		render:function(){
			return '<div style="display:inline-block;" ng-click="toolBar[0].handel()">{{toolBar[0].text}}</div>';
		}
	},
	{
		text:'确定',
		type:'button',
		class:'mini primary',
		handel:function(){
			alert($scope.toolBar[2].value);
		}
	},
	{
		text:'关键词',
		type:'input',
		value:'',
		label:'关键词',
		class:'mini',
		formClass:'fl',
		handel:function(){
			alert(1);
		}
	},
	{
		text:'确定',
		type:'button',
		class:'mini primary',
		handel:function(){
			alert($scope.toolBar[2].value);
		}
	},
	{
		text:'全部',
		type:'select',
		value: -1,
		arry:[
		{text:'p',value:1},
		{text:'k',value:2},
		{text:'u',value:3}
		],
		class:'mini',
		handel:function(){
			alert(1);
		}
	},
	{
		text:'搜索',
		type:'search',
		value: '',
		class:'d',
		handel:function(){
			alert(1);
		}
	},
	{
		text:'搜索',
		type:'search',
		label: 'true',
		labelClass:'teal',
		labelHandel:function(){
			this.label = '';
			this.value = '';
		},
		value: '',
		class:'mini',
		handel:function(){
			this.label = this.value;
			$http.get('https://www.baidu.com').then(function(resp){
				console.log(resp);
			},function(){});
		}
	}
	];

	$scope.form = [
		{
			label:'email',
			palceholder:'email',
			value:'',
			type:'text',
			name:'email',
			op:'RegExp',
			compareTo:'email',
			errorRequire:'邮箱',
			errorMsg:'邮箱格式错误',
		},
		{
			label:'手机号',
			palceholder:'手机号',
			type:'text',
			value:'',
			name:'phone',
			op:'RegExp',
			compareTo:'mobile',
			errorRequire:'手机号码',
			errorMsg:'手机号码格式错误'
		}
	];
}]);
app.directive('usernameReg', function($q, $timeout) {

	return {
		require: 'ngModel',
		link: function(scope, elm, attrs, ctrl) {

			var usernames = ['Jim', 'John', 'Jill', 'Jackie','yue'];

			ctrl.$asyncValidators.username = function(modelValue, viewValue) {
				console.log('modelValue:')
				console.log(modelValue);
				if (ctrl.$isEmpty(modelValue)) {
		      // consider empty model valid
		      return $q.resolve();
		  }

		  var def = $q.defer();

		  $timeout(function() {
		      // Mock a delayed response
		      if (usernames.indexOf(modelValue) === -1) {
		        // The username is available
		        def.resolve();
		    } else {
		    	def.reject();
		    }

		}, 2000);

		  return def.promise;
		};
	}
};
});


/**
 * [description] 值比较
 * @param  {parent} $rootScope) {	function   inherit(child, parent) {		child.prototype [description]
 * @return {[type]}             [description]
 */
app.directive('ngCompare', ['$rootScope',function ($rootScope) {

 	function inherit(child, parent) {
 		child.prototype = new parent();
 		child.prototype.constructor = child;
 	}

 	function CompareUtil(){}

 	CompareUtil.prototype.compareResult = function(){
 		var compare = this.getCompare(this.compare);
 		var compareTo = this.getCompareTo(this.compareTo);
		// console.log('compare:'+compare+" compareTo:"+compareTo);
		// console.log(this.op);
		switch (this.op) {
			case 'eqeq':
				// 等于
				return compare == compareTo;
				break;
			case 'eqeqeq':
				// 全等于
				return compare === compareTo;
				break;
			case 'lt':
				// 小于
				return compare < compareTo;
				break;
			case 'gt':
				// 大于
				return compare > compareTo;
				break;
			case 'lteq':
				// 小于等于
				return compare <= compareTo;
				break;
			case 'gteq':
				// 大于等于
				return compare >= compareTo;
				break;
			case 'RegExp':
				// 正则匹配

				// console.log(compareTo); 
				if(compareTo){
					return compareTo.test(compare);
				}
				
				break;
			default:
				// statements_def
				console.log('op value is error:'+this.op);
				break;
			}
		}
	CompareUtil.prototype.getCompare = function(value){
		//number
		if(!isNaN(value)){
			return value*1;
		}
		//date
		if(/^(\d{4})\/(\d{1,2})\/(\d{1,2})$/.test(value)){
			return new Date(value).getTime();
		}
		//string
		return value;
	}
	CompareUtil.prototype.getCompareTo = function(value){
		// console.log('getCompareTo:')
		// console.log(value);
		if(this.op == "RegExp"){
			switch (value) {
				case 'mobile':
					// 手机号
					return /^1\d{10}$/;
					break;
				case 'telephone':
					// 电话
					return /^0\d{2,3}-?\d{7,8}$/;
					break;
				case 'email':
					// 邮箱
					return /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/;
					break;
				case 'number':
					// 数字 0-9
					return /^[0-9]*$/;
					break;
				case 'carded':
					// 身份证号
					return /^\d{15}|\d{18}$/;
					break;
				default:
					// statements_def
					console.log('not define RegExp:'+value);
					break;
			}
		}else{
			return this.getCompare(value);
		}
	}



	/**
	 * @op  数值比较方式 eqeq,lt,gt
	 * @compare  值
	 * @compareTo 要比较的值
	 */
	 function Compare(op,compare,compareTo){
	 	this.op = op;
	 	this.compare = compare;
	 	this.compareTo = compareTo;
	 }

	 inherit(Compare,CompareUtil);


	 return {
	 	restrict: 'A',
	 	require: 'ngModel',
	 	link: function (scope, element, attrs,ctrl) {
	 		// $(element)
				// 	  .popup({
				// 	    position : 'top center',
				// 	    inline     : true,
				// 	    // target   : '.test.image',
				// 	    title    : 'My favorite dog',
				// 	    content  : 'My favorite dog would like other dogs as much as themselves'
				// 	  })
				// 	;
	 		var op = attrs.compareOp;			
	 		ctrl.$validators.compareTo = function(val) {
	 			// console.log(attrs.compareTo);
	 			
	 			if(op=="RegExp"){
	 				var compareTo = attrs.compareTo;
	 				// console.log('RegExp');
	 			}else{
	 				var compareTo = scope.$eval(attrs.compareTo);
	 			}

	 			var compare = new Compare(op,val,compareTo);
	 			console.log('val:'+val+" "+op+" compareTo:"+compareTo+" is "+compare.compareResult())

	 			if(!compare.compareResult() && val!='' && val!=null){
	 				// console.log($(element)[0]);
	 				$(element)
					  .popup({
					    position : 'top center',
					    title    : 'My favorite dog',
					    content  : 'My favorite dog would like other dogs as much as themselves'
					  })
					;
					$(element)
					  .popup('show');
	 			}else{
	 				$(element)
					  .popup('remove popup');
	 			}
	 			return compare.compareResult();

                // return val == scope.$eval(attrs.compareTo);
            };

            scope.$watch(attrs.compareTo, function() {
            	ctrl.$validate();
            });
        }
    };
}]);

 app.directive('myToolBar', ['$rootScope',function ($rootScope) {

 	return {
 		restrict: 'A',
 		scope:{
 			toolBar:'='
 		},
 		replace: true,
 		templateUrl:'tpl/toolbar.html',
 		link: function (scope, iElement, iAttrs) {
 			console.log('r');
 			console.log(scope.toolBar)
 		}
 	};
 }]);


 app.directive('myDirective', ['$http','$compile','$timeout',function ($http,$compile,$timeout) {

 	function getTemplate(item){
 		if(item.render){
 			return item.render();
 		}			
 		switch (item.type) {
 			case 'link':
 			return 'tpl/link.html';
 			break;
 			case 'button':
 			return '<button data-content="Hello. This is an inverted popup" data-variation="inverted" class="{{item.class}}"  ng-click="item.handel()">{{item.text}}</button>';
 			break;
 			case 'input':
 			return '<div class="{{item.class}}"><input type="text" placeholder="{{item.text}}" ng-model="item.value"></div>';
 			break;
 			case 'search':
 			return '<div class="{{item.class}}"><input type="text" placeholder="{{item.text}}" ng-model="item.value"><i class="circular search link icon" ng-click="item.handel()"></i></div>';
 			break;
 			case 'select':
 			return '<select class="{{item.class}}" ng-model="item.value" ng-change="item.handel()"><option value="-1" style="display:none;">请选择</option><option ng-value="op.value" ng-repeat="op in item.arry">{{op.text}}</option></select>';
 			break;
 			case 'downMenu':
 			return 'tpl/menu.html';
 			break;
 			default:			
 			break;
 		}
 	}

 	return {
 		restrict: 'A',
 		scope:{
 			item:'='
 		},
 		replace: true,
 		link: function (scope, element, iAttrs) {
			//getTemplate
			var el = $compile(getTemplate(scope.item))(scope);
			element.replaceWith(el);

			if(iAttrs.modelType=='select'){
				
				$timeout(function(){
					console.log($(element).find('button')[0]);
					$('.ui.dropdown').dropdown();		
					$(el).popup();			
				},100);	
			}	
		}
	};
}]);

/**
 * [description] <div class="ui text container" tool-bar-generate tool-bar = 'toolBar'></div>
 * @param  {parent} $compile) {	function   inherit(child, parent) {		child.prototype [description]
 * @return {[type]}           [description]
 */
app.directive('toolBarGenerate', ['$compile',function ($compile) {

 	function inherit(child, parent) {
 		child.prototype = new parent();
 		child.prototype.constructor = child;
 	}

 	function ToolBarGenerate(toolBar){
 		this.toolBar = toolBar;
 	}
 	ToolBarGenerate.prototype.init = function(element,scope){
 		if(typeof(this.toolBar) == 'string'){
 			this.toolBar = JSON.parse(this.toolBar);
 		}

 		if(this.toolBar.length == 0){
 			console.log('toolBar no data');
 			return;
 		}
 		new CommonBase();
 		for(var i in this.toolBar){
 			// console.log('--');
 			// console.log(this.toolBar[i]);
 			var obj = this.toolBar[i];
 			switch (obj.type) {
 				case 'link':
 				new LinkGenerate(obj).setBaseVar(obj).HTML_init(element,scope,i);
 				break;
 				case 'button':
 				new ButtonGenerate(obj).setBaseVar(obj).HTML_init(element,scope,i);
 				break;
 				case 'input':
 				new InputGenerate(obj).setBaseVar(obj).HTML_init(element,scope,i);
 				break;
 				case 'search':
 				new SerachGenerate(obj).setBaseVar(obj).HTML_init(element,scope,i);
 				break;
 				case 'select':
 				new SelectGenerate(obj).setBaseVar(obj).HTML_init(element,scope,i);
 				break;
 				case 'downMenu':
 				new DownMenuGenerate(obj).setBaseVar(obj).HTML_init(element,scope,i);
 				break;
 				default:		
 				console.log('not define type:'+obj.type)	
 				break;
 			}
 		}
 	};
	/**
	 * [Common description] 基础属性，公共成员
	 * @param {[type]} data [description]
	 */
	 function CommonBase(){}
	CommonBase.prototype.HTML_init = function(element,scope,i){
	 	var html;
	 	if(this.render){
	 		html = this.render();
	 		$(element).append($compile(html)(scope));
	 		return;
	 	}			
	 	switch (this.type) {
	 		case 'link':
	 		html =  'tpl/link.html';
	 		break;
	 		case 'button':
	 		html =  '<button class="ui button '+this.class+'"  ng-click="toolBar['+i+'].handel()">'+this.text+'</button>';
	 		break;
	 		case 'input':
	 		html = '<form class="ui form '+this.formClass+'" novalidate>'
	 		+'<div class="inline field">'
	 		+'<label ng-if="toolBar['+i+'].label">'+this.label+'</label>'
	 		+'<input type="text" placeholder="'+this.text+'" ng-model="toolBar['+i+'].value">'
	 		+'</div></form>';				
	 		break;
	 		case 'search':
	 		html =  '<div class="ui icon input '+this.class+'">'
	 		+'<input type="text" placeholder="'+this.text+'" ng-model="toolBar['+i+'].value">'
	 		+'<i class="circular search link icon" ng-click="toolBar['+i+'].handel()"></i>'
	 		+'</div><a class="ui label '+this.labelClass+'" ng-if="toolBar['+i+'].label">{{toolBar['+i+'].label}}<i class="delete icon" ng-click="toolBar['+i+'].labelHandel()"></i> </a>';
	 		break;
	 		case 'select':
	 		html =  '<select class="ui dropdown '+this.class+'" ng-model="toolBar['+i+'].value" ng-change="toolBar['+i+'].handel()">'
	 		+'<option value="-1" style="display:none;">'+this.text+'</option>'
	 		+'<option ng-value="op.value" ng-repeat="op in toolBar['+i+'].arry">{{op.text}}</option>'
	 		+'</select>';
	 		break;
	 		case 'downMenu':
	 		html =  'tpl/menu.html';
	 		break;
	 		default:
	 		console.log('html is not has'+this.type)			
	 		break;
	 	}
	 	$(element).append($compile(html)(scope));
	 }
	 CommonBase.prototype.setBaseVar = function(baseData){
	 	this.text = baseData.text;
	 	this.class = baseData.class;
	 	this.render = baseData.render;
	 	this.handel = baseData.handel;
	 	this.type = baseData.type;
	 	return this;
	 }


    /**
     * @param {[type]}
     * @param
     */
     function LinkGenerate(link){
     	this.title = link.title;
     	this.target = link.target;
     	this.href = link.href;
     }

     inherit(LinkGenerate,CommonBase);


    /**
     * @param text 
     */
     function ButtonGenerate(){}
     inherit(ButtonGenerate,CommonBase);



     /**
      * @param {[type]}
      */
      function InputGenerate(input){
      	this.label = input.label;
      	this.value = input.value;
      	this.formClass = input.formClass;
      }
      inherit(InputGenerate,CommonBase);

     /**
      * [SerachGenerate description]
      * @param {[type]} search [label,labelClass,labelHandel] 
      */
      function SerachGenerate(search){
      	this.label = search.label;
      	this.labelClass = search.labelClass;
      	this.labelHandel = search.labelHandel;
      }
      inherit(SerachGenerate,CommonBase);


      function SelectGenerate(){}
      inherit(SelectGenerate,CommonBase);

      function DownMenuGenerate(menu){
      	this.text = menu.text;
      	this.class = menu.class;
      	this.handel = menu.handel;
      	this.render = menu.render;
      	this.type = menu.type;
      }
      inherit(DownMenuGenerate,CommonBase);
      return {
      	restrict: 'A',
      	scope:{
      		toolBar:'='
      	},
      	link: function (scope, element, attrs) {
      		// console.log('g');
      		var bar = new ToolBarGenerate(scope.toolBar);
      		// console.log('bar');
      		// console.log(bar);

      		bar.init(element,scope);

      		scope.$watch('toolBar', function(newValue, oldValue, scope) {
      			console.log(scope.toolBar);
      		});


      	}
      };
  }])

app.directive('formGenerate', ['$compile',function ($compile) {


	function inherit(child, parent) {
		child.prototype = new parent();
		child.prototype.constructor = child;
	}

	function Form(form,name){
		this.form = form;
		this.name = name;
	}
	Form.prototype.init = function(element,scope){
		if(this.form.length == 0){
			return;
		}
		for (var i in this.form) {
			new Field(this.form[i]).HTML_init(element,scope,i,this.name);
		}
	};
	function Field(field){
		this.label = field.label; 				//label
		this.palceholder = field.palceholder;  	//input palceholder
		this.value = field.value; 				//input ng-model
		this.type = field.type; 				//input type
		this.name = field.name;					//input name
		this.op = field.op; 					//ng-compare compare-op
		this.compareTo = field.compareTo;		//ng-compare compare-to
		this.errorRequire = field.errorRequire;	//required error message
		this.errorMsg = field.errorMsg;			//ng-compare error message
		this.render = field.render;				//custom
	}

	// inherit(Field,Form);

	Field.prototype.HTML_init = function(element,scope,i,formName){
		var html;
	 	if(this.render){
	 		html = this.render();
	 		$(element).append($compile(html)(scope));
	 		return;
	 	}
	 	if(this.op){
	 		html = '<div class="inline field">'
    			+'<label>'+this.label+'{{testform.email}}</label>'
    			+'<input name="'+this.name+'" type="'+this.type+'" palceholder="'+this.palceholder+'" ng-model="form['+i+'].value" required ng-compare compare-to="'+this.compareTo+'" compare-op="'+this.op+'">'
  				+'</div>';
  			html+='<div class="ui error message" ng-messages="'+formName+'.'+this.name+'.$error" ng-if="'+formName+'.'+this.name+'.$dirty && '+formName+'.'+this.name+'.$invalid">'
    			+'<div ng-message="required">'+this.errorRequire+'</div>'
    			+'<div ng-message="compareTo">'+this.errorMsg+'</div>'
    			+'</div>';
	 	}else{
	 		html = '<div class="inline field">'
    			+'<label>'+this.label+'</label>'
    			+'<input name="'+this.name+'" type="'+this.type+'" palceholder="'+this.palceholder+'" ng-model="form['+i+'].value" required >'
  				+'</div>';
  			html+='<div class="ui error message" ng-messages="'+formName+'.'+this.name+'.$error" ng-if="'+formName+'.'+this.name+'.$dirty && '+formName+'.'+this.name+'.$invalid">'
    			+'<div ng-message="required">'+this.errorRequire+'</div>'
    			+'</div>';
	 	}	
	 	
	 	$(element).append($compile(html)(scope));
	}


	return {
		restrict: 'A',
		scope:{
			form:'='
		},
		link: function (scope, element, attr) {
			console.log('form-data:');
			console.log(scope.form);
			console.log(attr.name);
			var formName = attr.name;
			new Form(scope.form,formName).init(element,scope);
		}
	};
}])